package com.jwtproject.bootserver.security.provider;


import com.jwtproject.bootserver.exception.ProjectException;
import com.jwtproject.bootserver.security.token.MyAuthenticationToken;
import com.jwtproject.bootserver.status.ProjectStatusEnum;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

public class MyUsernameAuthenticationProvider extends CustomAbstractUserDetailsAuthenticationProvider {

    private UserDetailsService userDetailsService;

    private PasswordEncoder passwordEncoder;


    public MyUsernameAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }


    /**
     * 自定义验证
     * @param user
     * @param authentication
     * @throws AuthenticationException
     */
    @Override
    protected void additionalAuthenticationChecks(UserDetails user, Authentication authentication) throws AuthenticationException {

        try {
            boolean matches = String.valueOf(authentication.getCredentials()).equals(user.getPassword());
            // 密码验证
            if (!matches) {
                throw new ProjectException(ProjectStatusEnum.USER_NOT_EXIST);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new UsernameNotFoundException("用户密码验证失败,原因是：" + e.getMessage() );
        }
    }


    /**
     * 创建权限对象
     * @param principal
     * @param authentication
     * @param user
     * @return
     */
    @Override
    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        MyAuthenticationToken result = new MyAuthenticationToken(principal, authentication.getCredentials(), user.getAuthorities());
        result.setDetails(user);
        return result;
    }


    /**
     * 检索用户
     * @param username
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected UserDetails retrieveUser(String username, Authentication authentication) throws AuthenticationException {
        UserDetails loadedUser;
        try {
            loadedUser = this.getUserDetailsService().loadUserByUsername(username);
        } catch (UsernameNotFoundException var6) {
            throw var6;
        } catch (Exception var7) {
            throw new InternalAuthenticationServiceException(var7.getMessage(), var7);
        }

        if(loadedUser == null) {
            throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
        } else {
            return loadedUser;
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return MyAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public UserDetailsService getUserDetailsService() {
        return userDetailsService;
}

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

//    public PasswordEncoder getPasswordEncoder() {
//        return passwordEncoder;
//    }

//    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
//        this.passwordEncoder = passwordEncoder;
//    }
}
